package fr.uniscol.http;

import java.io.IOException;
import java.util.Collections;
import java.util.Enumeration;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

import org.apache.log4j.Logger;
import org.springframework.web.bind.annotation.RequestMethod;

public class HTTPLoggerFilter implements Filter {

	private static Logger log = Logger.getLogger(HTTPLoggerFilter.class);
	
	@Override
	public void init(final FilterConfig config) throws ServletException {
		// Intentionally left blank.
	}

	@Override
	public final void destroy() {
		// Intentionally left blank.
	}

	@Override
	public final void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain) throws IOException, ServletException {
		/*
		 * This filter is only able to handle HTTP, so we bypass anything else.
		 */
		if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
			chain.doFilter(request, response);
			return;
		}

		this.doFilter((HttpServletRequest) request, (HttpServletResponse) response, chain);
	}

	private final void doFilter(final HttpServletRequest request, final HttpServletResponse response, final FilterChain chain) throws IOException,
			ServletException {
		this.log(request);

		final HttpServletResponseWrapper wrapper = new HttpServletResponseWrapper(response);

		chain.doFilter(request, wrapper);

		//this.log(wrapper);
	}

	@SuppressWarnings("unchecked")
	/*
	 * When using Servlet API 3.0, remove casting to Enumeration<String>, as
	 * this is the actual return type already.
	 */
	private final void log(final HttpServletRequest request) {
		final StringBuilder message = new StringBuilder();

		message.append(String.format("--> %1$s %2$s", request.getMethod(), request.getRequestURI()));

		/*for (final String headerName : Collections.list((Enumeration<String>) request.getHeaderNames()))
			for (final String headerValue : Collections.list((Enumeration<String>) request.getHeaders(headerName)))
				message.append(String.format(" %s=%s", headerName, headerValue));
*/
        // log params
        message.append("[");
        Enumeration<String> names = request.getParameterNames();
        String name = null;
        while(names.hasMoreElements()){
            name = names.nextElement();            
            message.append(name + "=" + request.getParameter(name));
            message.append(" | ");                
        }
        message.append("]");
        
		log.debug(message.toString());
	}

	private final void log(final HttpServletResponseWrapper response) {
		final StringBuilder message = new StringBuilder();

		/*message.append(String.format("<-- %1$d", response.));

		for (final String headerName : response.getResponse().)
			for (final String headerValue : response.getHeaders(headerName))
				message.append(String.format(" %s=%s", headerName, headerValue));

		log.debug(message.toString());*/
	}
}
